<template>
  <div class="img-box">
    <el-upload
        class="avatar-uploader"
        action="http://localhost:8018/file/uploadImg"
        list-type="picture-card"
        :before-upload="beforeUpload"
        :on-success="handleImageSuccess"
        :on-remove="handleRemove"
        :on-preview="handlePictureCardPreview"
        :file-list="fileList"
    >
      <el-icon class="avatar-uploader-icon">
        <Plus />
      </el-icon>
    </el-upload>
  </div>

  <el-dialog v-model="dialogVisible" width="90%" top="20px">
    <img w-full :src="dialogImageUrl" alt="Preview Image" />
  </el-dialog>
</template>

<script lang="ts" setup>
import { PropType, ref, watch} from 'vue'
import { UploadProps, ElMessage, UploadUserFile } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'

// 定义 props, 接收父组件传来的 imgList
const props = defineProps({
  imgList: {
    type: [String, Array] as PropType<string | string[]>,
    required: true,
  }
})

const imageUrls = ref<string[]>([]) // 图片地址暂存列表
const fileList = ref<UploadUserFile[]>([]) // 上传文件列表
const emit = defineEmits(['update:imgList'])

watch(() => props.imgList,
    (newVal) => {
      syncFileList(newVal);
    },
    { immediate: true } // 立即执行一次监听器
);

// 创建一个函数来同步 imgList 和 fileList
function syncFileList(imgList: string | string[]): void {
  if (typeof imgList === 'string') {
    // 如果是字符串，则分割并过滤掉空字符串
    const images = imgList.split(',').filter(item => item.trim() !== '');
    fileList.value = images.map((imgName) => ({
      name: imgName,
      url: `http://localhost:8018/file/image?imageName=${encodeURIComponent(imgName)}`,
    }));
    imageUrls.value = images;
  }
  // else if (Array.isArray(imgList)) {
  //   // 如果已经是数组，则直接赋值
  //   imageUrls.value = imgList;
  //   fileList.value = imgList.map((imgName) => ({
  //     name: imgName,
  //     url: `http://localhost:8018/file/image?imageName=${encodeURIComponent(imgName)}`,
  //   }));
  // }
  //
  updateParentImgList();
}

// 将数组重新组合成逗号分隔的字符串并通知父组件
function updateParentImgList() {
  const join = imageUrls.value.join(',');
  if (join.length > 0) {
    emit('update:imgList', join);
  } else {
    emit('update:imgList', imageUrls.value);
  }
}

// 上传成功
const handleImageSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
  const newImageUrl = response.data.url;
  const newFileName = response.data.name;
  imageUrls.value.push(newImageUrl) // 添加到 imageUrls
  fileList.value.push({
    name: newFileName,
    url: newImageUrl,
    raw: uploadFile.raw,
  });
  syncFileList(imageUrls.value);
}

const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
  // 允许的图片类型
  const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/webp'];

  if (!allowedTypes.includes(rawFile.type)) {
    ElMessage.error('图片格式不支持，请上传 JPG, PNG, GIF, BMP 或 WebP 格式的图片!');
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('图片不得大于 2MB!');
    return false;
  }
  return true;
};

const dialogImageUrl = ref('')
const dialogVisible = ref(false)

// 图片预览
const handlePictureCardPreview: UploadProps['onPreview'] = uploadFile => {
  dialogImageUrl.value = uploadFile.url as any
  dialogVisible.value = true
}

// 移除图片时同步更新 imageUrls 和 fileList
const handleRemove = (file: UploadUserFile) => {
  const index = fileList.value.indexOf(file);

  if (index > -1) {
    fileList.value.splice(index, 1);

    // 更新 imageUrls，只保留等号后面的内容
    imageUrls.value = fileList.value
      .map(item => {
        // 使用字符串的 split 方法按等号分割，并取分割后的第二部分
        const parts = item.url!.split('=');
        return parts.length > 1 ? parts[1] : '';
      })
      .filter(urlPart => urlPart.trim() !== ''); // 过滤掉空字符串
  }

  updateParentImgList();
};
</script>

<style lang="scss" scoped>
.img-box {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  .image-container {
    position: relative;
    display: inline-block;
    cursor: pointer;
    img {
      border: 1px dashed var(--el-border-color);
      font-size: 28px;
      color: #8c939d;
      width: 150px;
      height: 150px;
      text-align: center;
      border-radius: 10px;
      object-fit: cover;
      margin: 0 1px;
    }
  }
}


.icon-container {
  position: absolute;
  top: 0;
  left: 0;
  // top: 50%;
  // left: 50%;
  // transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.5);
  color: #fff;
  width: 150px;
  height: 150px;
  border-radius: 10px;
  opacity: 0;
  transition: opacity 0.3s;
  .el-icon {
    font-size: 20px;
    margin: 0 10px;
  }
}

.image-container:hover .icon-container {
  opacity: 1;
}

.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}

</style>

<style lang="scss" scoped>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}

.el-upload-list__item {
  align-items: center;
}

.el-dialog__body {
  margin-top: 20px;
  text-align: center;

  img {
    min-height: 50vh;
  }
}
</style>
